<?php
    /**
     * test.php
     *
     * Created by PhpStorm.
     * author: liuml  <liumenglei0211@163.com>
     * DateTime: 2018/7/27  11:08
     */

    namespace app\wxapi\controller\v1;

    use think\Config;
    use think\Controller;
    use think\Request;
    use \data\service\PushMessage as PMSG;

    class ApiController extends Controller
    {
        public $method;

        /**
         * 初始化api
         */
        protected function _initialize()
        {
            parent::_initialize();
            $this->method = $this->request->action();
            $this->createRequestLog();
            $this->verifySign();
            $this->addressable();
        }

        /**
         * 签名校验
         * @return bool
         */
        protected function verifySign()
        {
            if (in_array($this->method, $this->notNeedSign())) {
                return true;
            }
            $request     = Request::instance();
            $sign        = $request->header('sign') ? : $request->get('sign');
            $requestTime = $request->header('requestTime') ? : $request->get('requestTime');
            $appid       = $request->header('appid') ? : $request->get('appid');
            $ip          = $appid ? : $request->ip();
            $appkey      = Config::get('wxapiToken.' . $ip) ? : 'There is no appkey';
            // 判断IP是否在白名单
            if ($appkey == 'There is no appkey') {
                abort(403, '非法访问');
            }
            // 签名校验
            if ($this->encryptSign($ip, $appkey, $requestTime) != $sign) {
                abort(401, '签名校验错误');
            }
            return true;
        }

        /**
         * 加密签名
         * @param $ip
         * @param $appkey
         * @param $requestTime
         * @return string
         */
        protected function encryptSign($ip, $appkey, $requestTime)
        {
            return md5(base64_encode($ip . $appkey . $requestTime));
        }

        /**
         * 统一处理响应数据
         * @return \think\response\Json
         */
        public static function runResponse($code = 1, $msg = '成功', $data = NULL, $status = 200, $header = [], $options = [])
        {
            $response = [
                'code'    => $code,
                'message' => $msg,
            ];

            if (!empty($data)) {
                $response['data'] = $data;
            }
            /* // 设置跨域header
            if(!empty($header)){
                $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*";
                $header = [
                    "Access-Control-Allow-Origin" => $host_name,
                ];
            }*/
            return json($response, $status, $header, $options);
        }

        /**
         * 列出不需要日志的方法
         * @return array
         */
        protected function excludeMethod()
        {
            return [
                'test',
                'printlog',
            ];
        }

        /**
         * 判断方法是否可访问
         */
        protected function addressable()
        {
            $addressable = [
                'createmessage',
                'printlog',
            ];

            if (!in_array($this->method, $addressable)) {
                abort(404, '请求路径不存在');
            }
            return true;
        }

        /**
         * 列出不需要签名的方法
         * @return array
         */
        public function notNeedSign()
        {
            return [
                'printlog',
            ];
        }

        /**
         * 生成请求日志
         * @return bool
         */
        protected function createRequestLog()
        {
            if (in_array($this->method, $this->excludeMethod())) {
                return true;
            }
            $pushService = new PMSG();
            $request     = Request::instance();
            $data        = [
                'url'            => $request->url(true),
                'method'         => $request->method(),
                'ip'             => $request->ip(1),
                'request_header' => json_encode($request->header(), JSON_UNESCAPED_UNICODE),
                'request_body'   => json_encode($request->post(), JSON_UNESCAPED_UNICODE),
                'type'           => 1,
                'create_time'    => $_SERVER['REQUEST_TIME'],
            ];
            $pushService->addMessageLog($data);
            return true;
        }

        /**
         * 生成响应日志
         * @return bool
         */
        protected function createResponseStatus($url, $method, $request_body, $error_code, $error_msg, $response, $source = 'WX')
        {
            $pushService = new PMSG();
            $data        = [
                'url'            => $url,
                'method'         => $method,
                'type'           => 2,
                'request_header' => '',
                'request_body'   => $request_body,
                'error_code'     => $error_code,
                'error_msg'      => $error_msg,
                'response'       => $response,
                'source'         => $source,
                'create_time'    => time(),
            ];
            $pushService->addMessageLog($data);
            return true;
        }
    }